package pl.rpr.rozklad;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

class Przystanek {
  private String adres;
  private String nazwa;

  public Przystanek() {
    this.adres = new String();
    this.nazwa = new String();
  }

  public Przystanek(String adres, String nazwa) {
    this.adres = new String(adres);
    this.nazwa = new String(nazwa);
  }

  public String getAdres() {
    return adres;
  }

  public void setAdres(String adres) {
    this.adres = new String(adres);
  }

  public String getNazwa() {
    return nazwa;
  }

  public void setNazwa(String nazwa) {
    this.nazwa = new String(nazwa);
  }
}

class PrzystankiAdapter extends ArrayAdapter<Przystanek> {
  private List<Przystanek> przystanki;
  private List<Przystanek> kopiaZapasowaPrz;
  private List<Przystanek> filtrowane;
  private Context          context;
  private PrzystankiFilter filter;

  public PrzystankiAdapter(Context context, int textViewResourceId, List<Przystanek> objects) {
    super(context, textViewResourceId, objects);
    this.context = context;
    this.przystanki = objects;
    this.kopiaZapasowaPrz = new ArrayList<Przystanek>(przystanki);
    this.filtrowane = new ArrayList<Przystanek>(przystanki);
    this.filter = new PrzystankiFilter();
  }

  @Override
  public int getCount() {
    return przystanki.size();
  }

  @Override
  public Przystanek getItem(int position) {
    return przystanki.get(position);
  }

  @Override
  public long getItemId(int position) {
    return 0;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    String adresPrzystanku = przystanki.get(position).getAdres();
    String nazwaPrzystanku = przystanki.get(position).getNazwa();
    if (convertView == null) {
      convertView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.przystanki, parent, false);
    }

    TextView nazwaTV = (TextView) convertView.findViewById(R.id.nazwaP);
    nazwaTV.setText(nazwaPrzystanku);

    TextView adresTV = (TextView) convertView.findViewById(R.id.adresP);
    adresTV.setText(adresPrzystanku);

    return convertView;
  }

  @Override
  public Filter getFilter() {
    if (filter == null)
      filter = new PrzystankiFilter();
    return filter;
  }

  private class PrzystankiFilter extends Filter {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
      constraint = constraint.toString().toLowerCase();
      FilterResults result = new FilterResults();
      if (constraint != null && constraint.toString().length() > 0) {
        List<Przystanek> kopiaFil = new ArrayList<Przystanek>();
        List<Przystanek> kopiaPrz = new ArrayList<Przystanek>();
        synchronized (this) {
          kopiaPrz.addAll(kopiaZapasowaPrz);
        }
        for (int i = 0, l = kopiaPrz.size(); i < l; ++i) {
          Przystanek p = kopiaPrz.get(i);
          if (p.getNazwa().toLowerCase().contains(constraint))
            kopiaFil.add(p);
        }
        result.values = kopiaFil;
        result.count = kopiaFil.size();
      } else {
        synchronized (this) {
          result.values = kopiaZapasowaPrz;
          result.count = kopiaZapasowaPrz.size();
        }
      }
      return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
      filtrowane = (List<Przystanek>) results.values;
      notifyDataSetChanged();
      clear();
      for (int i = 0, l = filtrowane.size(); i < l; ++i)
        add(filtrowane.get(i));
    }

  }
}

class PrzystankiTextWatcher implements TextWatcher {
  PrzystankiAdapter adapter;

  public PrzystankiTextWatcher(PrzystankiAdapter ad) {
    this.adapter = ad;
  }

  public void onTextChanged(CharSequence s, int start, int before, int count) {
    adapter.getFilter().filter(s);
  }

  public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  }

  public void afterTextChanged(Editable s) {
  }
}

public class Przystanki extends ListActivity implements CONST {
  private PrzystankiAdapter     adapter;
  private PrzystankiTextWatcher filtrPrzystankow;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    new Polaczenie(this).sprawdzPolaczenie();

    String htmlDoParsowania = wczytajStringPrzystankow(ADRES_PRZYSTANKOW);

    List<Przystanek> przystanki = new ArrayList<Przystanek>();
    przystanki = parsujPrzystanki(htmlDoParsowania);

    adapter = new PrzystankiAdapter(this, R.layout.przystanki, przystanki);

    filtrPrzystankow = new PrzystankiTextWatcher(adapter);

    EditText search = new EditText(this);
    search.addTextChangedListener(filtrPrzystankow);
    getListView().addHeaderView(search, null, true);

    getListView().setAdapter(adapter);
  }

  @Override
  protected void onListItemClick(ListView parent, View view, int position, long id) {
    super.onListItemClick(parent, view, position, id);
    Intent intent = new Intent(view.getContext(), AutobusyZPrzystankow.class);
    TextView adresTV = (TextView) view.findViewById(R.id.adresP);
    String adres = adresTV.getText().toString();
    intent.putExtra("adresAutobusu", adres);
    startActivity(intent);
  }

  @Override
  protected void onResume() {
    super.onResume();
    new Polaczenie(this).sprawdzPolaczenie();
  }

  @Override
  protected void onRestart() {
    super.onRestart();
    new Polaczenie(this).sprawdzPolaczenie();
  }

  private String wczytajStringPrzystankow(String adresPrzystankow) {
    HttpClient klient = new DefaultHttpClient();
    HttpGet zadanie = new HttpGet(adresPrzystankow);
    HttpResponse odpowiedz = null;
    String htmlDoParsowania = null;
    InputStream strumienWejsciowy = null;
    BufferedReader czytnik = null;
    StringBuilder stringBuilder = new StringBuilder();
    String linia = null;

    try {
      odpowiedz = klient.execute(zadanie);
      strumienWejsciowy = odpowiedz.getEntity().getContent();
      czytnik = new BufferedReader(new InputStreamReader(strumienWejsciowy, "ISO-8859-2"));
      while ((linia = czytnik.readLine()) != null) {
        stringBuilder.append(linia);
      }
      strumienWejsciowy.close();
    } catch (ClientProtocolException e) {
      e.printStackTrace();
    } catch (IllegalStateException e) {
      e.printStackTrace();
    } catch (UnsupportedEncodingException e1) {
      e1.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    htmlDoParsowania = stringBuilder.toString();
    return htmlDoParsowania;
  }

  private ArrayList<Przystanek> parsujPrzystanki(String htmlDoParsowania) {
    ArrayList<Przystanek> przystanki = new ArrayList<Przystanek>();
    Pattern patPrzystankow = Pattern.compile(RE_PRZYSTANKI);
    Matcher matPrzystankow = patPrzystankow.matcher(htmlDoParsowania);
    while (matPrzystankow.find()) {
      Przystanek tmp = new Przystanek(ADRES_ROZKLADOW + matPrzystankow.group(1), matPrzystankow.group(2));
      przystanki.add(tmp);
    }
    return przystanki;
  }
}